<template>
  <el-popover trigger="hover" :width="400">
    <template #reference>
      <el-button>
        <span>{{ currentValue }} - {{ codeToName }}</span>
        <vab-icon icon="arrow-down-s-line" />
      </el-button>
    </template>
    <div>
      <el-radio-group
        v-model="listType"
        style="margin-bottom: var(--el-margin)"
      >
        <el-radio-button label="province">按省份</el-radio-button>
        <el-radio-button label="city">按城市</el-radio-button>
      </el-radio-group>
      <div v-if="listType === 'province'">
        <el-space wrap>
          <el-button
            v-for="item in provinceList"
            :key="item.n"
            size="small"
            @click="handleClickLetter(item.n)"
          >
            {{ item.n }}
          </el-button>
        </el-space>
        <el-scrollbar ref="scrollbarRef" always height="300px">
          <div ref="listRef">
            <div v-for="item in cityListByProvince" :key="item.p.n">
              <el-divider
                :class="'el-city-' + item.p.l"
                content-position="left"
              >
                {{ item.p.n }}
              </el-divider>
              <el-space wrap>
                <el-button
                  v-for="city in item.c"
                  :key="city.n"
                  text
                  @click="handleChangeValue(city.c)"
                >
                  {{ city.n }}
                </el-button>
              </el-space>
            </div>
          </div>
        </el-scrollbar>
      </div>
      <div v-if="listType === 'city'">
        <el-space wrap>
          <el-button
            v-for="(item, key) in cityListByLetter"
            :key="key"
            size="small"
            @click="handleClickLetter(key)"
          >
            {{ key }}
          </el-button>
        </el-space>
        <el-scrollbar ref="scrollbarRef" always height="300px">
          <div ref="listRef">
            <div v-for="(item, key) in cityListByLetter" :key="key">
              <el-divider :class="'el-city-' + key" content-position="left">
                {{ key }}
              </el-divider>
              <div>
                <el-space wrap>
                  <el-button
                    v-for="city in item"
                    :key="city.n"
                    text
                    @click="handleChangeValue(city.c)"
                  >
                    {{ city.n }}
                  </el-button>
                </el-space>
              </div>
            </div>
          </div>
        </el-scrollbar>
      </div>
    </div>
  </el-popover>
</template>

<script setup>
  import provinceData from "./tools/province";
  import cityData from "./tools/city";

  const props = defineProps({
    modelValue: {
      type: String,
    },
  });

  const emit = defineEmits(["update:modelValue"]);
  const value = ref("");
  const currentValue = ref();
  const codeToName = ref("");
  const visible = ref(false);
  const provinceList = ref([]);
  const cityListByProvince = ref([]);
  const cityListByLetter = ref({});
  const allCities = ref();
  const listType = ref("province");
  const scrollbarRef = ref(null);
  const listRef = ref(null);

  const handleGetCities = () => {
    const cData = cityData;
    const cities = [];
    for (const cid in cData) {
      const city = cData[cid];
      cities.push(city);
    }
    return cities;
  };

  const handleChangeValue = (val) => {
    currentValue.value = val;
    visible.value = false;
    const value = val;
    emit("update:modelValue", value);
  };

  const handleClickLetter = (letter) => {
    if (letter === "直辖市") letter = "Z1";
    else if (letter === "港澳") letter = "Z2";
    const className = `.el-city-${letter}`;
    const offsetTop = listRef.value.querySelectorAll(className)[0].offsetTop;
    const listTop = listRef.value.offsetTop;
    scrollbarRef.value.setScrollTop(offsetTop - listTop);
  };

  const handleGetProvinceByLetter = () => {
    const provinces = {
      A: { n: "A", p: [], c: [] },
      F: { n: "F", p: [], c: [] },
      G: { n: "G", p: [], c: [] },
      H: { n: "H", p: [], c: [] },
      J: { n: "J", p: [], c: [] },
      L: { n: "L", p: [], c: [] },
      N: { n: "N", p: [], c: [] },
      Q: { n: "Q", p: [], c: [] },
      S: { n: "S", p: [], c: [] },
      T: { n: "T", p: [], c: [] },
      X: { n: "X", p: [], c: [] },
      Y: { n: "Y", p: [], c: [] },
      Z: { n: "Z", p: [], c: [] },
      Z1: { n: "直辖市", p: [], c: [] },
      Z2: { n: "港澳", p: [], c: [] },
    };
    for (const c in provinceData) {
      const item = provinceData[c];
      provinces[item.l].p.push(item);
    }
    provinceList.value = provinces;
  };

  const handleGetCityByProvince = () => {
    const _provinceList = provinceList.value;
    const _cityListByProvince = [];
    const cData = cityData;

    const otherCities = [
      { p: { n: "直辖市", p: "86", l: "Z1" }, c: [] },
      { p: { n: "港澳", p: "86", l: "Z2" }, c: [] },
    ];

    for (const letter in _provinceList) {
      const letterProvince = _provinceList[letter];

      for (let i = 0; i < letterProvince.p.length; i++) {
        const province = letterProvince.p[i];
        const pid = province.c;

        const provinceCities = {
          p: province,
          c: [],
        };

        for (const cid in cData) {
          const city = cData[cid];
          if (pid === city.p) provinceCities.c.push(city);
        }

        if (letter === "Z1") otherCities[0].c.push(cData[pid]);
        else if (letter === "Z2") otherCities[1].c.push(cData[pid]);
        else _cityListByProvince.push(provinceCities);
      }
    }

    cityListByProvince.value = _cityListByProvince.concat(otherCities);
  };

  const handleGetCityByLetter = () => {
    const cData = cityData;
    const _cityListByLetter = {
      A: [],
      B: [],
      C: [],
      D: [],
      E: [],
      F: [],
      G: [],
      H: [],
      J: [],
      K: [],
      L: [],
      M: [],
      N: [],
      P: [],
      Q: [],
      R: [],
      S: [],
      T: [],
      W: [],
      X: [],
      Y: [],
      Z: [],
    };
    for (const cid in cData) {
      const city = cData[cid];
      _cityListByLetter[city.l].push(city);
    }
    cityListByLetter.value = _cityListByLetter;
  };

  watch(
    currentValue,
    () => {
      if (!currentValue.value) return;
      codeToName.value = cityData[currentValue.value].n;
    },
    { immediate: true }
  );

  onBeforeMount(() => {
    value.value = props.modelValue;
    currentValue.value = props.modelValue;
    allCities.value = handleGetCities();
    handleGetProvinceByLetter();
    handleGetCityByProvince();
    handleGetCityByLetter();
  });
</script>
